import { IAbility, IContext, IParam, verifyNodeLinkCond, deepCopy, typeOf, UILogicParamService, UILogicParamType } from "@/core";
/**
 * 界面逻辑测试
 * 基于template/src/ui-service/{{appEntities}}/{{uiLogics}}-ui-logic-base.ts.hbs生成  
 * @export
 * @class UilogictestUILogicBase
 */
export class UilogictestUILogicBase {

    /**
     * 返回结果
     *
     * @private
     * @type {*}
     * @memberof UilogictestUILogicBase
     */
    private result: any;

    /**
     * 行为附加参数
     *
     * @type {*}
     * @memberof UilogictestUILogicBase
     */
    public additionalParam: IParam = {};

    /**
     * 界面逻辑上下文
     *
     * @private
     * @type {IContext}
     * @memberof UilogictestUILogicBase
     */
    private appContext!: IContext;

    /**
     * 界面逻辑视图参数
     *
     * @private
     * @type {IParam}
     * @memberof UilogictestUILogicBase
     */
    private viewParam!: IParam;

    /**
     * 默认逻辑处理参数名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private defaultParamName: string = '';

    /**
     * 应用上下文参数名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private navContextParamName: string = '';

    /**
     * 视图参数名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private navViewParamParamName: string = '';

    /**
     * 当前容器参数名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private activeContainerParamName: string = '';

    /**
     * 当前激活部件参数名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private activeCtrlParamName: string = '';

    /**
     * 当前激活视图对象名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private activeViewParamName: string = '';

    /**
     * 上一次调用返回参数名称
     *
     * @private
     * @type {string}
     * @memberof UilogictestUILogicBase
     */
    private lastReturnParamName: string = '';

    /**
     * 逻辑参数Map
     *
     * @private
     * @type {Map<string, IParam>}
     * @memberof UilogictestUILogicBase
     */
    private logicParamMap: Map<string, IParam> = new Map();

    /**
     * 绑定上一次调用返回参数
     *
     * @memberof UilogictestUILogicBase
     */
    public bindLastReturnParam(value: any) {
        const lastReturnParam = this.logicParamMap.get(this.lastReturnParamName);
        if (lastReturnParam) {
            lastReturnParam.bind(value);
        }
    }

    /**
     * 默认逻辑处理参数
     *
     * @memberof UilogictestUILogicBase
     */
    get defaultParam(): any {
        return this.logicParamMap.get(this.defaultParamName);
    }

    /**
     * 上下文数据（包括应用上下文和逻辑局部上下文参数）
     *
     * @readonly
     * @memberof UilogictestUILogicBase
     */
    get context() {
        const navContextParam = this.logicParamMap.get(this.navContextParamName);
        if (navContextParam) {
            return navContextParam.getReal();
        } else {
            return this.appContext;
        }
    }

    /**
     * 视图参数数据（包括外部传入视图参数和逻辑局部视图参数）
     *
     * @readonly
     * @memberof UilogictestUILogicBase
     */
    get viewParams() {
        const navViewParamParam = this.logicParamMap.get(this.navViewParamParamName);
        if (navViewParamParam) {
            return navViewParamParam.getReal();
        } else {
            return this.viewParam;
        }
    }

    /**
     * 获取逻辑处理参数
     *
     * @param {string} key 逻辑处理参数的codeName
     * @memberof UIActionContext
     */
    private getParam(key: string): any {
        return this.logicParamMap.get(key);
    }

   	/**
     * Creates an instance of UilogictestUILogicBase
     * 
     * @param {IParam} [opts={}]
     * @memberof UilogictestUILogicBase
     */
    constructor(opts: IParam = {}) { }

    /**
     * 逻辑参数模型
     *
     * @private
     * @type {any[]}
     * @memberof UilogictestUILogicBase
     */
    private logicParamModels: any[] = [
        { 
            name: "传入变量", 
            codeName: "Default", 
            default: true, 
            entityParam: true,
        },
        { 
            name: "消息弹窗返回值", 
            codeName: "msgReturn", 
            simpleParam: true,
        },
        { 
            name: "逻辑查询数据", 
            codeName: "logicData", 
            entityParam: true,
        }
    ]

    /**
    * 初始化逻辑参数
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof UilogictestUILogicBase
    */
    private initLogicParams<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, $event: MouseEvent, ability: T) {
        this.appContext = deepCopy(context);
        this.viewParam = deepCopy(viewParams);
        this.additionalParam = { data, $event, ctrl: ability.viewCtx.ctrl, actionContext: ability };
        this.logicParamModels.forEach((model: IParam) => {
            if (model.default) {
                this.defaultParamName = model.codeName;
            }
            if (model.navContextParam) {
                this.navContextParamName = model.codeName;
            }
            if (model.navViewParamParam) {
                this.navViewParamParamName = model.codeName;
            }
            if (model.activeContainerParam) {
                this.activeContainerParamName = model.codeName;
            }
            if (model.activeCtrlParam) {
                this.activeCtrlParamName = model.codeName;
            }
            if (model.activeViewParam) {
                this.activeViewParamName = model.codeName;
            }
            if (model.lastReturnParam) {
                this.lastReturnParamName = model.codeName;
            }
            const uiLogicParamInstance = UILogicParamService.getLogicParamInstance(this, model, { data, context, viewParams, $event, ctrl: ability.viewCtx.ctrl, actionContext: ability });
            this.logicParamMap.set(model.codeName, uiLogicParamInstance);
        });
    }

    /**
    * 执行界面逻辑之前
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof UilogictestUILogicBase
    */
    private beforeExecute<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, event: MouseEvent, ability: T) {
        this.initLogicParams(context, viewParams, data, event, ability);
    }

    /**
    * 执行界面逻辑
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof UilogictestUILogicBase
    */
    public async execute<T extends IAbility>(context: IContext, viewParams: IParam, data: IParam, event: MouseEvent, ability: T) {
        try {
            this.beforeExecute(context, viewParams, data, event, ability);
            await this.execute_Begin_node();
            return this.result;
        } catch (error: any) {
            throw new Error(`${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }
    
    /**
     * 执行 开始 节点
     *
     * @protected
     * @memberof UilogictestUILogicBase
     */
    protected async execute_Begin_node() {
        this.result = this.defaultParam.getReal();
        console.log(`已完成执行 开始节点，操作参数数据如下:`);
        if (this.logicParamMap && (this.logicParamMap.size > 0)) {
            for (let [key, value] of this.logicParamMap) {
                console.log(key, deepCopy(value.getReal()));
            }
        }
        console.log(`即将执行实体行为节点`);
        await this.execute_DEACTION1_node();
    }
    
    /**
     * 执行 实体行为 节点
     *
     * @protected
     * @memberof UilogictestUILogicBase
     */
    protected async execute_DEACTION1_node() {
        try {
            const dstParam = this.getParam("Default");
            if (dstParam) {
                const service = await App.getDataService("IBIZBOOK", this.context);
                if (service && service["Get"] && service["Get"] instanceof Function) {
                    const getTempContext = (data: IParam) => {
                        const tempContext = deepCopy(this.context);
                        if (data) {
                            Object.assign(tempContext, data);
                        }
                        return tempContext;
                    }
                    const tempContext = getTempContext(dstParam.getReal());
                    const res = await service["Get"](tempContext, dstParam.getReal() ? dstParam.getReal() : {});
                    if (res.success && res.data) {
                        const retParam = this.getParam("logicData");
                        if (retParam) {
                            retParam.bind(res.data);
                        }
                        this.bindLastReturnParam(res.data);
                    } else {
                        throw new Error(`执行实体行为失败`);
                    }
                }
            } else {
                throw new Error(`操作参数缺失！`);
            }
            console.log(`已完成执行 实体行为节点，操作参数数据如下:`);
            if (this.logicParamMap && (this.logicParamMap.size > 0)) {
                for (let [key, value] of this.logicParamMap) {
                    console.log(key, deepCopy(value.getReal()));
                }
            }
            console.log(`即将执行消息弹窗节点`);
            await this.execute_MSGBOX1_node();
        } catch (error: any) {
            throw new Error(`执行 实体行为 节点 ${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }
    
    /**
     * 执行 结束 节点
     *
     * @protected
     * @memberof UilogictestUILogicBase
     */
    protected async execute_END1_node() {
    }
    
    /**
     * 执行 消息弹窗 节点
     *
     * @protected
     * @memberof UilogictestUILogicBase
     */
    protected async execute_MSGBOX1_node() {
        return new Promise<void>((resolve: any) => {
            const options = {};
            Object.assign(options, { okText: '是', cancelText: '否' });
            const msgBoxParam: any = this.getParam("msgReturn");
            const data: any = msgBoxParam ? msgBoxParam.getReal() : {};
            Object.assign(options, { type: 'warning' });
            const msgBox = App.getDialogHelper();
            const handleMsgBox = async (result: boolean) => {
                const resultText = result ? 'yes' : 'no';
                msgBoxParam.bind(resultText);
                this.bindLastReturnParam(resultText);
                console.log(`已完成执行 消息弹窗节点，操作参数数据如下:`);
                if (this.logicParamMap && (this.logicParamMap.size > 0)) {
                    for (let [key, value] of this.logicParamMap) {
                        console.log(key, deepCopy(value.getReal()));
                    }
                }
                const linkCond_0 = {
                	name: '',
                	logicType: 'GROUP',
                	notMode: false,
                	groupOP: 'AND',
                	childLogics: [
                		{
                	name: 'msgReturn 等于(=) yes',
                	logicType: 'SINGLE',
                	condOP: "EQ",
                	verifyValue: this.getParam("msgReturn").getReal(),
                	value: "yes"
                }
                	],
                }
                if (verifyNodeLinkCond(linkCond_0)) {
                    console.log(`即将执行实体行为节点`);
                    await this.execute_DEACTION2_node();
                }
                const linkCond_1 = {
                	name: '',
                	logicType: 'GROUP',
                	notMode: false,
                	groupOP: 'AND',
                	childLogics: [
                		{
                	name: 'msgReturn 等于(=) no',
                	logicType: 'SINGLE',
                	condOP: "EQ",
                	verifyValue: this.getParam("msgReturn").getReal(),
                	value: "no"
                }
                	],
                }
                if (verifyNodeLinkCond(linkCond_1)) {
                    console.log(`即将执行结束节点`);
                    await this.execute_END1_node();
                }
                resolve();
            }
            Object.assign(options, {
                title: data && data.title ? data.title : "直接删除！",
                content: data && data.message ? data.message : ``,
                ok: () => { handleMsgBox(true); },
                cancel: () => { handleMsgBox(false); }
            })
            msgBox.custom(options);
        })
    }
    
    /**
     * 执行 实体行为 节点
     *
     * @protected
     * @memberof UilogictestUILogicBase
     */
    protected async execute_DEACTION2_node() {
        try {
            const dstParam = this.getParam("Default");
            if (dstParam) {
                const service = await App.getDataService("IBIZBOOK", this.context);
                if (service && service["Remove"] && service["Remove"] instanceof Function) {
                    const getTempContext = (data: IParam) => {
                        const tempContext = deepCopy(this.context);
                        if (data) {
                            Object.assign(tempContext, data);
                        }
                        return tempContext;
                    }
                    const tempContext = getTempContext(dstParam.getReal());
                    const res = await service["Remove"](tempContext, dstParam.getReal() ? dstParam.getReal() : {});
                    if (res.success && res.data) {
                        this.bindLastReturnParam(res.data);
                    } else {
                        throw new Error(`执行实体行为失败`);
                    }
                }
            } else {
                throw new Error(`操作参数缺失！`);
            }
            console.log(`已完成执行 实体行为节点，操作参数数据如下:`);
            if (this.logicParamMap && (this.logicParamMap.size > 0)) {
                for (let [key, value] of this.logicParamMap) {
                    console.log(key, deepCopy(value.getReal()));
                }
            }
            console.log(`即将执行结束节点`);
            await this.execute_END1_node();
        } catch (error: any) {
            throw new Error(`执行 实体行为 节点 ${error && error.message ? error.message : '发生未知错误！'}`);
        }
    }

}
